home *** CD-ROM | disk | FTP | other *** search
- unit HintsU;
- {$ifdef Ver80} { Delphi 1.0x }
- {$define DelphiLessThan3}
- {$endif}
- {$ifdef Ver90} { Delphi 2.0x }
- {$define DelphiLessThan3}
- {$endif}
- {$ifdef Ver93} { C++ Builder 1.0x }
- {$define DelphiLessThan3}
- {$endif}
-
- interface
-
- uses
- WinProcs, WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, Mask, DBCtrls, Db, DBTables, ExtCtrls;
-
- type
- TForm1 = class(TForm)
- btnExit: TButton;
- DBEdit1: TDBEdit;
- DBEdit2: TDBEdit;
- DBEdit3: TDBEdit;
- DBEdit4: TDBEdit;
- Table1: TTable;
- DataSource1: TDataSource;
- DBNavigator1: TDBNavigator;
- procedure FormCreate(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure btnExitClick(Sender: TObject);
- procedure DBEditEnter(Sender: TObject);
- procedure DBEditExit(Sender: TObject);
- private
- HintWnd: THintWindow;
- Control: TControl;
- procedure ActivateOnOff(Sender: TObject);
- function CalcHintRect(MaxWidth: Integer;
- const AHint: string; HintWnd: THintWindow): TRect;
- function CalcHintTopLeft(Control: TControl): TPoint;
- procedure MoveControl(Control: TWinControl; ShowControl: Boolean);
- procedure WMMove(var Msg: TWMMove);
- message wm_Move;
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.DFM}
-
- procedure TForm1.ActivateOnOff(Sender: TObject);
-
- {$ifdef DelphiLessThan3}
- function ForegroundTask: Boolean;
- begin
- { Does the active window map onto some object in this app? }
- Result := FindControl(GetActiveWindow) <> nil
- end;
- {$endif}
-
- begin
- if Assigned(Control) then
- { If we lost focus, hide the tooltip. If we gain focus, show it }
- MoveControl(HintWnd, ForegroundTask)
- end;
-
- function TForm1.CalcHintRect(MaxWidth: Integer;
- const AHint: string; HintWnd: THintWindow): TRect;
- {$ifdef DelphiLessThan3}
- var
- Buf: array[0..511] of Char;
- begin
- Result := Rect(0, 0, MaxWidth, 0);
- { Ask Windows to do the hard calculation work }
- DrawText(HintWnd.Canvas.Handle, StrPCopy(Buf, AHint), -1, Result,
- DT_CALCRECT or DT_LEFT or DT_WORDBREAK or DT_NOPREFIX);
- { Add some breathing room }
- Inc(Result.Right, 6);
- Inc(Result.Bottom, 2);
- {$else}
- begin
- { Delphi 3+ makes this method available }
- Result := HintWnd.CalcHintRect(Screen.Width, AHint, nil)
- {$endif}
- end;
-
- function TForm1.CalcHintTopLeft(Control: TControl): TPoint;
- const
- HintOffset = 4;
- begin
- { Where should it go? }
- Result := Point(Control.Left + HintOffset, Control.Top + Control.Height);
- Result := ClientToScreen(Result);
- end;
-
- { Move hint, and hide/show it as specified }
- procedure TForm1.MoveControl(Control: TWinControl; ShowControl: Boolean);
- const
- Visibility: array[Boolean] of Cardinal = (SWP_HIDEWINDOW, SWP_SHOWWINDOW);
- begin
- with HintWnd do
- SetWindowPos(Handle, HWND_TOPMOST, Left, Top, Width, Height,
- Visibility[ShowControl] or SWP_NOACTIVATE)
- end;
-
- { Move the hint if the form is moved }
- procedure TForm1.WMMove(var Msg: TWMMove);
- begin
- inherited;
- { If we have a control's tooltip showing }
- if Assigned(Control) then
- with CalcHintTopLeft(Control) do
- { We'll move it }
- MoveWindow(HintWnd.Handle, X, Y, HintWnd.Width, HintWnd.Height, True);
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- { These two ensure the manufactured hints disappear and reappear as appropriate }
- Application.OnActivate := ActivateOnOff;
- Application.OnDeActivate := ActivateOnOff;
- end;
-
- { Make sure the hint goes away if the form is shrunk so the control is not visible }
- procedure TForm1.FormResize(Sender: TObject);
- begin
- { If we have a control's tooltip showing }
- if Assigned(Control) then
- { Hide it if the control is no longer visible, else show it }
- MoveControl(HintWnd, PtInRect(
- Rect(0, 0, ClientWidth, ClientHeight),
- Point(Control.Left, Control.Top)))
- end;
-
- procedure TForm1.btnExitClick(Sender: TObject);
- begin
- Application.Terminate
- end;
-
- { When control gains focus, display the hint }
- procedure TForm1.DBEditEnter(Sender: TObject);
- var
- HintRect: TRect;
- begin
- { Create instance of currently registered hint window class }
- if not Assigned(HintWnd) then
- HintWnd := HintWindowClass.Create(Self);
- { Use current VCL hint colour }
- HintWnd.Color := Application.HintColor;
- Control := TControl(Sender);
- { How big should it be? }
- HintRect := CalcHintRect(Screen.Width, Control.Hint, HintWnd);
- with CalcHintTopLeft(Control) do
- OffsetRect(HintRect, X, Y);
- { Show it }
- HintWnd.ActivateHint(HintRect, Control.Hint)
- end;
-
- { When control loses focus, remove the hint }
- procedure TForm1.DBEditExit(Sender: TObject);
- begin
- Control := nil;
- { Keep object, but destroy underlying window }
- HintWnd.ReleaseHandle;
- end;
-
- end.
-